const ImmediatePriority = 1; // 立即执行的优先级, 级别最高  点击事件， iniput 
const UserBlockingPriority = 2; // 用户阻塞级别的优先级    滚动，拖拽
const NormalPriority = 3; // 正常的优先级   render 动画， ajax 网络请求
const LowPriority = 4; // 低优先级   分析统计
const IdlePriority = 5;// 最低阶的优先级, 可以被闲置的那种    console


function getCurrentTime() {
    return performance.now();
}
class SimpleScheduler {
    constructor() {
        // cb priortiyLevel expirationTime
        this.taskQueue = [];
        this.isPerformingWork = false; // 是否正在执行任务 防止任务执行多次
        const channel = new MessageChannel();
        this.port = channel.port2; // 发消息
        channel.port1.onmessage = this.performWorkUnitDeaLine.bind(this);
    }
    scheduleCallback(priortiyLevel, callback) {
        var currentTime = getCurrentTime();
        var timeout;
        // 超时时间越小， 优先级越高
        switch (priortiyLevel) {
            case ImmediatePriority:
            timeout = -1;
            break;
            case UserBlockingPriority:
            timeout = 250;
            break;
            case IdlePriority:
            timeout = 1073741823; // 32位操作系统 v8引擎对应的最大值
            break;
            case LowPriority:
            timeout = 10000;
            break;
            case NormalPriority:
                timeout = 5000;
            default:
                timeout = 5000;
            break;
        }
        const task = {
            callback,
            priortiyLevel,
            expirationTime: currentTime + timeout,
        }
        this.push(this.taskQueue, task);
        if (!this.isPerformingWork) {
            this.isPerformingWork = true;
            this.port.postMessage(null); //触发消息
        }

    }
    performWorkUnitDeaLine() {
        console.log(this, '执行任务');
        this.isPerformingWork = true;
        this.workloop();
        this.isPerformingWork = false;
    }
    workloop() {
        // 执行任务
        let currentTask = this.peak(this.taskQueue);
        // []
        while(currentTask) {
            let cb = currentTask.callback;
            cb && cb();
            this.pop(this.taskQueue);
            currentTask = this.peak(this.taskQueue);
        }
    }
    push (queue, task) {
        queue.push(task);
        // 排序 从小到大
        queue.sort((a, b) => a.expirationTime - b.expirationTime);

    }
    peak(queue) {
        return queue[0] || null;


    }
    pop(queue) {
        return queue.shift();
    }
}


const s = new SimpleScheduler();
// 可以掉用多次   代码是可以乱写的  但是执行的顺序是固定的
// sort()  [ ]
s.scheduleCallback(UserBlockingPriority, () => {
    console.log('2');
})

s.scheduleCallback(NormalPriority, () => {
    console.log('3');
})

s.scheduleCallback(ImmediatePriority, () => {
    console.log('1');
})

